package com.sinothk.gpserver.modules.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sinothk.gpserver.data.DataConstant;
import com.sinothk.gpserver.modules.biz.data.GroupData;
import com.sinothk.gpserver.modules.biz.entity.GroupDto;
import com.sinothk.gpserver.modules.biz.entity.GroupEntity;
import com.sinothk.gpserver.modules.biz.entity.GroupMemberEntity;
import com.sinothk.gpserver.modules.biz.entity.GroupMessageEntity;
import com.sinothk.gpserver.modules.biz.mapper.GroupMapper;
import com.sinothk.gpserver.modules.biz.mapper.GroupMemberMapper;
import com.sinothk.gpserver.modules.biz.service.IGroupMemberService;
import com.sinothk.gpserver.modules.biz.service.IGroupMessageService;
import com.sinothk.gpserver.modules.biz.service.IGroupService;
import com.sinothk.gpserver.modules.comm.serialNumber.service.SerialNumberService;
import com.sinothk.gpserver.modules.system.entity.LoginEntity;
import com.sinothk.gpserver.modules.system.entity.UserEntity;
import com.sinothk.gpserver.modules.system.mapper.UserMapper;
import com.sinothk.gpserver.util.PageDataUtil;
import com.sinothk.server.support.annotation.callback.BizException;
import com.sinothk.server.support.entity.PageData;
import com.sinothk.server.support.entity.PageVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * <p>
 * 群(俱乐部) 服务实现类
 * </p>
 *
 * @author Liang Y.t.
 * @since 2021-08-28
 */
@Service
public class GroupServiceImpl extends ServiceImpl<GroupMapper, GroupEntity> implements IGroupService {

    @Resource
    private GroupMapper groupMapper;
    @Resource
    private GroupMemberMapper groupMemberMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private IGroupMemberService groupMemberService;
    @Autowired
    private SerialNumberService snService;
    @Autowired
    private IGroupMessageService groupMessageService;

    /**
     * 查询分页数据
     *
     * @param pageVo 分页参数
     * @return PageData
     */
    @Override
    public PageData<GroupEntity> page(PageVo<GroupEntity> pageVo) {
        Page<GroupEntity> page = new Page<>(pageVo.getPageNum(), pageVo.getPageSize());
        IPage<GroupEntity> iPage = groupMapper.selectPage(page, null);
        return new PageDataUtil<GroupEntity>().create(iPage);
    }

    @Override
    public PageData<GroupEntity> pageForMember(PageVo<GroupEntity> pageVo) {
        LoginEntity user = (LoginEntity) SecurityUtils.getSubject().getPrincipal();
        Page<GroupEntity> page = new Page<>(pageVo.getPageNum(), pageVo.getPageSize());
        IPage<GroupEntity> iPage = groupMapper.pageForMember(page, user.getAccount());
        return new PageDataUtil<GroupEntity>().create(iPage);
    }

    @Override
    @Transactional(rollbackFor = BizException.class)
    public boolean create(GroupEntity groupEntity) {

        if (StringUtils.isBlank(groupEntity.getGroupName())) throw new BizException("俱乐部名称不能为空");

        LoginEntity loginUser = (LoginEntity) SecurityUtils.getSubject().getPrincipal();

        UserEntity user = userMapper.selectByAccount(loginUser.getAccount());
        int roomCards = user.getRoomCards();
        if (roomCards < GroupData.ADD_GROUP_CARDS) throw new BizException("房卡不足! 需要[" + GroupData.ADD_GROUP_CARDS + "]，请联系管理员");
        user.setRoomCards(roomCards - GroupData.ADD_GROUP_CARDS);
        userMapper.updateById(user);

        // 创建俱乐部
        QueryWrapper<GroupEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(GroupEntity::getGroupName, groupEntity.getGroupName());
        List<GroupEntity> list = this.list(wrapper);
        if (list.size() > 0) throw new BizException("俱乐部名称已被占用");
        groupEntity.setGroupNo(snService.generateSerialNumberByModelCode("俱乐部"));
        groupEntity.setManagers(loginUser.getAccount());
        groupEntity.setCreateBy(loginUser.getAccount());
        groupEntity.setGroupMemberSize(1);
        groupEntity.setGroupMemberMax(5000);
        this.save(groupEntity);

        // 查询
        LambdaQueryWrapper<GroupEntity> wrapperDb = new LambdaQueryWrapper<>();
        wrapperDb.eq(GroupEntity::getGroupNo, groupEntity.getGroupNo());
        GroupEntity groupDb = this.getOne(wrapperDb);

        // 将用户设置为群管理员
        GroupMemberEntity groupMember = new GroupMemberEntity();
        groupMember.setGroupId(groupDb.getId());
        groupMember.setGroupName(groupDb.getGroupName());
        groupMember.setCreateBy(groupDb.getCreateBy());
        groupMember.setMemberAccount(loginUser.getAccount());
        groupMember.setInviteBy("");
        groupMember.setGroupRole(DataConstant.RoleGroup.G_ADMIN);
        groupMemberService.save(groupMember);

        // 消息
        GroupMessageEntity msg = new GroupMessageEntity();
        msg.setGroupId(groupDb.getId());
        msg.setTitle(groupDb.getGroupName() + "生成了！");
        msg.setContent(groupDb.getGroupName() + "，国民MOBA手游大作！5V5王者峡谷、公平对战、还原MOBA经典体验；契约之战、五军对决、边境突围等，带来花式作战乐趣！10秒实时跨区匹配，与好友开黑上分，向最强王者进击！多款英雄任凭选择，一血、五杀、超神，实力碾压，收割全场！敌军即将到达战场，王者召唤师快来集结好友，准备团战.....");
        msg.setCreateBy(loginUser.getUserName());
        groupMessageService.save(msg);

        return true;
    }

    @Override
    public GroupDto getGroupById(String id, String userAccount) {
        GroupDto groupDto = new GroupDto();
        GroupEntity groupEntity = this.getById(id);
        groupDto.setGroupEntity(groupEntity);

        // 获取当前用户和群的关系
        LambdaQueryWrapper<GroupMemberEntity> wrapperGroupMember = new LambdaQueryWrapper<>();
        wrapperGroupMember.eq(GroupMemberEntity::getGroupId, id)
                .eq(GroupMemberEntity::getMemberAccount, userAccount);
        groupDto.setGroupMember(groupMemberMapper.selectOne(wrapperGroupMember));

        // 判断当前用户是否是成员
        LambdaQueryWrapper<GroupMemberEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(GroupMemberEntity::getGroupId, groupEntity.getId())
                .eq(GroupMemberEntity::getMemberAccount, userAccount);
        List<GroupMemberEntity> list = groupMemberMapper.selectList(wrapper);
        groupDto.setHasJoined(list != null && list.size() > 0);

        return groupDto;
    }
}
